import axios, { Axios, type AxiosRequestConfig } from 'axios'

/** 请求响应数据类型 */
export interface ResultResponse<T = any> {
  code: number
  message: string
  data: T
}

/** 创建一个错误 */
function errorCreat(message: string) {
  console.log(message)
  return Promise.reject(new Error(message))
}

class HttpRequest {
  baseUrl: string
  timeout: number

  constructor() {
    this.baseUrl = import.meta.env.VITE_APP_BASE_URL
    this.timeout = 5000
  }

  setInterceptor(instance: Axios, tipErrorMessage: boolean = true) {
    instance.interceptors.request.use(
      config => {
        console.log('config===>', config.url, 'data===>', config.data, 'params===>', config.params)
        return config
      },
      error => {
        // 错误提示
        console.log('请求错误')
        return Promise.reject(error)
      }
    )
    instance.interceptors.response.use(
      response => {
        console.log('response===>' + response.config.url, response.data)
        const dataAxios = response.data
        if (dataAxios.code !== 200) {
          // 是否提示错误信息
          tipErrorMessage && console.log('错误提示', dataAxios.message)
          return Promise.reject(dataAxios)
        }
        return dataAxios
      },
      error => {
        // 取消请求 无需进行错误提示处理
        if (axios.isCancel(error)) {
          console.log('Request canceled', error.message)
          return Promise.reject(error)
        }
        // 网络错误
        if (error && error.message.indexOf('Network Error') !== -1) {
          console.log('网络错误')
          return Promise.reject(error)
        }
        // 请求超时
        if (error && error.message.indexOf('timeout') !== -1) {
          console.log('请求超时')
          return Promise.reject(error)
        }
        // 其他错误
        if (error && error.response) {
          switch (error.response.status) {
            case 404:
              return errorCreat('请求地址出错')
            case 403:
              return errorCreat('拒绝访问')
            case 500:
              return errorCreat('服务器内部错误')
            case 503:
              return errorCreat('服务不可用')
            case 504:
              return errorCreat('网关超时')
            default:
              return errorCreat('网络错误')
          }
        }
        return errorCreat('网络错误')
      }
    )
  }

  request<T>(options: AxiosRequestConfig, tipErrorMessage: boolean = true) {
    const instance = axios.create({
      baseURL: this.baseUrl,
      timeout: options.timeout || this.timeout || 5000
    })
    this.setInterceptor(instance, tipErrorMessage)
    return instance<ResultResponse<T>>(options)
  }

  get<T>(url: string, params = {}, tipErrorMessage: boolean = true) {
    return this.request<T>(
      {
        method: 'get',
        url,
        params
      },
      tipErrorMessage
    )
  }

  post<T>(url: string, data = {}, tipErrorMessage: boolean = true) {
    return this.request<T>(
      {
        method: 'post',
        url,
        data
      },
      tipErrorMessage
    )
  }

  // 上传
  upload<T>(url: string, data = {}, tipErrorMessage: boolean = true) {
    return this.request<T>(
      {
        method: 'post',
        url,
        data,
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      },
      tipErrorMessage
    )
  }

  // 下载
  download<T>(url: string, data = {}, tipErrorMessage: boolean = true) {
    return this.request<T>(
      {
        method: 'post',
        url,
        data,
        responseType: 'blob'
      },
      tipErrorMessage
    )
  }
}

export default new HttpRequest()
